'''
实验名称：系统信息显示
实验平台：核桃派BOX + 0.96寸OLED屏。
'''

#导入相关库
import os, board, busio

#IP lib
import socket, fcntl, struct

#oled lib
import adafruit_ssd1306

from time import sleep

font_file = 'font5x8.bin'

#构建I2C对象
i2c = busio.I2C(board.SCL2, board.SDA2)

#构建oled对象,01Studio配套的OLED地址为0x3C
display = adafruit_ssd1306.SSD1306_I2C(128, 64, i2c, addr=0x3C)


def getCPUtemperature():
    res = os.popen('cat /sys/class/thermal/thermal_zone0/temp').readline()
    return '%.1f' % (int(res) / 1000)


#返回CPU使用率百分比（%），字符类型
def getCPUuse():
    return (str(os.popen("top -b -n1 | awk '/Cpu\(s\):/ {print $2}'").readline().strip()))


# 采集RAM信息，返回单位是kB
# Index 0: 总内存                                                               
# Index 1: 已使用内存                                                               
# Index 2: 剩余内存                                                               
def getRAMinfo():
    p = os.popen('free')
    i = 0
    while 1:
        i = i + 1
        line = p.readline()
        if i == 2:
            return (line.split()[1:4])


# 返回SD卡容量大小，单位是GB                    
# Index 0: 总容量                                                        
# Index 1: 已用空间                                                        
# Index 2: 剩余空间                                                    
# Index 3: 使用率（%）                                                 
def getDiskSpace():
    p = os.popen("df -h /")
    i = 0
    while 1:
        i = i + 1
        line = p.readline()
        if i == 2:
            return (line.split()[1:5])


#获取本地IP地址，返回字符
def getIP(ifname):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

    #异常处理
    try:
        return socket.inet_ntoa(fcntl.ioctl(
            s.fileno(),
            0x8915,  # SIOCGIFADDR 
            struct.pack('256s', ifname[:15].encode('utf-8'))
        )[20:24])

    except OSError:
        return ('0.0.0.0')


ip_node = 0

while True:
    #采集CPU温度信息
    CPU_temp = getCPUtemperature()


    #采集CPU使用率
    CPU_usage = getCPUuse()

    #内存信息，转化成MB
    RAM_stats = getRAMinfo()
    RAM_total = int(int(RAM_stats[0]) / 1000)
    RAM_used = int(int(RAM_stats[1]) / 1000)
    RAM_free = int(int(RAM_stats[2]) / 1000)
    RAM_perc = str(round(RAM_used / RAM_total * 100)) + '%'

    #sd卡容量信息
    DISK_stats = getDiskSpace()
    DISK_total = DISK_stats[0]
    DISK_used = DISK_stats[1]
    DISK_perc = DISK_stats[3]  #使用百分比

    #无线网络IP信息
    Wlan0_IP = getIP("wlan0")


    #以太网IP信息
    Eth0_IP = getIP("eth0")


    #清空显示屏
    display.fill(0)

    #oled显示
    display.text('CPU Temp: ' + CPU_temp + ' C', 0, 0, 1, font_name=font_file)
    display.text(
        'RAM: ' + str('%.1f' % (RAM_used / 1000)) + 'G' + '/' + str('%.1f' % (RAM_total / 1000)) + 'G' + ' ' + RAM_perc,
        0, 12, 1, font_name=font_file)  #GB
    display.text('DISK: ' + str(DISK_used) + '/' + str(DISK_total) + ' ' + DISK_perc, 0, 24, 1, font_name=font_file)

    display.text('WiFi: ' + Wlan0_IP, 0, 40, 1, font_name=font_file)
    display.text('eth0: ' + Eth0_IP, 0, 52, 1, font_name=font_file)

    display.show()

    sleep(1)  #延时，数据更新间隔
